package com.xiaodou.mjf.application.basic.service.impl;

import java.util.List;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;
import com.xiaodou.mjf.application.basic.repository.MenuRepository;
import com.xiaodou.mjf.application.basic.repository.OperatorRepository;
import com.xiaodou.mjf.application.basic.repository.RoleRepository;
import com.xiaodou.mjf.application.basic.service.MenuService;
import com.xiaodou.mjf.application.basic.utils.OperatorUtils;
import com.xiaodou.mjf.entity.basic.Menu;
import com.xiaodou.mjf.entity.basic.Operator;
import com.xiaodou.mjf.entity.basic.Role;
import com.xiaodou.mjf.infrastructure.common.app.JpaSimpleService;


/***
 *
 * Menu业务访问实现
 * @author XiaoDou.com Code Generator
 * @version 1.0
 * 2014-10-29 17:37:52
 *
 */
@Service @Transactional
public class MenuServiceImpl extends JpaSimpleService<Menu,String> implements MenuService{

	Logger logger = LoggerFactory.getLogger(MenuServiceImpl.class);

    @Resource
    MenuRepository menuRepository;

    @Resource
    OperatorRepository operatorRepository;

    @Resource
    RoleRepository roleRepository;

    @Override
    protected JpaRepository<Menu, String> getRepository() {
        return menuRepository;
    }

    @Override
    public Menu save(Menu menu) {
        menu.setParent(get(menu.getParent().getId()));
        String path = menu.getPath();
        menu.setPath(menu.getParent().getPath() + menu.getParent().getId() + ",");

        menu.setStatus(Menu.NORMAL);
        menu.setPlatform(menu.getParent().getPlatform());

        menuRepository.save(menu);

        List<Menu> childrens = menuRepository.findByPathLike(path);
        for(Menu e:childrens){
            e.setPath(e.getPath().replace(path, menu.getPath()));
        }

        menuRepository.save(childrens);

        OperatorUtils.removeCache(OperatorUtils.CACHE_MENU_LIST);

        return menu;
    }

    @Override
    public List<Menu> list() {
        List<Menu> menus = menuRepository.findAll(new Specification<Menu>() {

            @Override
            public Predicate toPredicate(Root<Menu> root, CriteriaQuery<?> query,
                                         CriteriaBuilder cb) {
                Predicate p1 = cb.equal(root.get("status").as(Integer.class), Menu.NORMAL);
                Predicate p2 = cb.notEqual(root.get("id").as(String.class), Menu.ROOT_ID);
                Predicate p3 = cb.notEqual(root.get("id").as(String.class), Menu.MERACHANT_ROOT_ID);
                Predicate p4 = cb.equal(root.get("platform").as(Integer.class),Menu.PLATFORM_CONSOLE);
                return query.where(p1,p2,p3,p4).getRestriction();

            }
        },new Sort(Sort.Direction.ASC,Menu.SORT));

        return menus;
    }

    @Override
    public List<Menu> getMenusByOperator(String operatorId) {

        List<Menu> allMenu = Lists.newArrayList();
        Operator operator = operatorRepository.findOne(operatorId);
        List<Role> roles = operator.getRoles();
        for(Role role:roles) {
            List<Menu> menus = role.getMenus();
            allMenu.addAll(menus);
        }
        return allMenu;
    }

    @Override
    public List<Menu> getFrontMenus(Menu menu) {

        List<Menu> menus = menuRepository.findAll((root,query,cb) -> {

            Predicate p1 = cb.equal(root.get("status").as(Integer.class), Menu.NORMAL);
            Predicate p2 = cb.notEqual(root.get("id").as(String.class), Menu.FRONT_ROOT_ID);
            Predicate p3 = cb.equal(root.get("platform").as(Integer.class), Menu.PLATFORM_PORTAL);

            return query.where(p1,p2,p3).getRestriction();
        },new Sort(Sort.Direction.ASC,Menu.SORT));

        return menus;
    }
    
    @Override
    public List<Menu> getMerchantMenus(Menu menu) {

        List<Menu> menus = menuRepository.findAll((root,query,cb) -> {

            Predicate p1 = cb.equal(root.get("status").as(Integer.class), Menu.NORMAL);
            Predicate p2 = cb.notEqual(root.get("id").as(String.class), Menu.MERACHANT_ROOT_ID);
            Predicate p3 = cb.equal(root.get("platform").as(Integer.class), Menu.PLATFORM_MERACHANT);

            return query.where(p1,p2,p3).getRestriction();
        },new Sort(Sort.Direction.ASC,Menu.SORT));

        return menus;
    }

    @Override
    public Menu getMenuByUrl(String url) {
        return menuRepository.getByUrl(url);
    }


    @Override
    public List<Menu> findByParentId(String parentId) {
        return menuRepository.findByParentId(parentId);
    }

	@Override
	public List<Menu> findByParentIdAndPlatform(String parentId,
			Integer platform) {
		return menuRepository.findByParentIdAndPlatform(parentId, platform);
	}
}

